package com.example.foo.api.web.order;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alipay.api.AlipayApiException;
import com.ruoyi.common.core.domain.AjaxResult;
import com.example.foo.api.boot.TokenHelper;
import com.example.foo.order.model.Order;
import com.example.foo.order.service.OrderService;
import com.example.foo.order.service.TransactionService;
import com.example.foo.weixin.domain.params.TransactionDoResp;


@RestController
@RequestMapping(value = "/transaction")
public class TransactionController {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @org.springframework.beans.factory.annotation.Autowired(required=true)
    private TransactionService transactionService;

    @Autowired
    private OrderService orderService;

    /**
     * 发起订单交易
     * 微信公众号支付
     */
    @RequestMapping(value = "do")
    public AjaxResult transactionDo(@RequestBody Order order, HttpServletRequest request) {
        Long userId = TokenHelper.verifyToken();
        Long uid = order.getUid();
        String goodsType = order.getGoodsType();
        if (!Objects.equals(userId, uid)) {
            return AjaxResult.error(403, "Access Forbidden");
        }
        if(order.getGoodsType().equals(Order.GoodsType.GOODS.text)){
            int count = orderService.findPayGoodsNumByUid(uid,goodsType);
            if(count > 0){
                return AjaxResult.error(400,"每个用户只能办理一次");
            }
        }
        order.setPayType(Order.PayType.WX_JSAPI.text);
        TransactionDoResp resp = transactionService.transactionDo(order,request);
        return AjaxResult.successData(resp);
    }

    /**
     * 发起订单交易
     * 微信App支付
     */
    @RequestMapping(value = "wxAppPay")
    public AjaxResult wxAppPay(@RequestBody Order order, HttpServletRequest request) {
        Long userId = TokenHelper.verifyToken();
        Long uid = order.getUid();
        if (!Objects.equals(userId, uid)) {
            return AjaxResult.error(403, "Access Forbidden");
        }
        order.setPayType(Order.PayType.WX_APP.text);
        TransactionDoResp resp = transactionService.transactionDo(order,request);
        return AjaxResult.successData(resp);
    }

    /**
     * 发起订单交易
     * 支付宝支付
     */
    @RequestMapping(value = "alipay")
    public AjaxResult alipay(@RequestBody Order order) throws AlipayApiException {
        Long userId = TokenHelper.verifyToken();
        Long uid = order.getUid();
        if (!Objects.equals(userId, uid)){
            return AjaxResult.error(403, "Access Forbidden");
        }
        order.setPayType(Order.PayType.ALI_APP.text);
        String resp = transactionService.aliAppPay(order);
        return AjaxResult.successData(resp);
    }

    /**
     * 用于168（goods）查询是否有已支付订单
     */
    @RequestMapping(value = "queryPayStatus")
    public AjaxResult queryStatus(@RequestBody Map<String, String> param) {
        Long userId = TokenHelper.verifyToken();
        String uidStr = param.get("uid");
        String goodsType = param.get("goodsType");
        Long uid = Long.parseLong(uidStr);
        if (!Objects.equals(userId, uid)) {
            return AjaxResult.error(403, "Access Forbidden");
        }
        AjaxResult result = AjaxResult.success();
        int count = orderService.findPayGoodsNumByUid(uid,goodsType);
        if (count == 1) {
            result.put("payStatus","1");
        }else if(count == 0){
            result.put("payStatus","0");
        }
        return result;
    }

    @RequestMapping(value = "payCallback")
    public String payCallback(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("进入微信支付异步通知");
        String resXml="";
        try{
            //
            InputStream is = request.getInputStream();
            //将InputStream转换成String
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            resXml=sb.toString();
            logger.info("微信支付异步通知请求包: {}", resXml);
            return transactionService.payBack(resXml);
        }catch (Exception e){
            logger.error("微信支付回调通知失败",e);
            String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            return result;
        }
    }

    /**
     * <pre>
     * 第一步:验证签名,签名通过后进行第二步
     * 第二步:按一下步骤进行验证
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     * </pre>
     *
     * @return
     */
    @RequestMapping("alipayCallback")
    public String callback(HttpServletRequest request) {
        System.out.println("进入支付宝支付异步通知");
        return transactionService.aliPayBack(request);
    }


}
